interface ICommand
{
    excute():void;
}
interface IReceive
{
    aciton():void;
}
interface IInvoke
{
    runCommand(command?:ICommand):void;
}

class CommandRecevie implements IReceive
{
    aciton(): void {
        console.log("task action receive");
    }
}
class LaunchCommand implements ICommand
{
    private _receive:IReceive;
    excute(): void {
        console.log("Launch!");
        this._receive.aciton()
    }
    constructor(receive:IReceive)
    {
        this._receive = receive;
    }
}
class StopCommand implements ICommand
{
    excute(): void {
        console.log("Stop!");
        this._receive.aciton();
    }
    private _receive: IReceive;
    constructor(receive:IReceive)
    {
        this._receive = receive;
    }   
}
class Invoker implements IInvoke
{
    private command:ICommand[];
    constructor()
    {
     this.command = [];
    }
    addCommand(commands:ICommand):void
    {
      this.command.push(commands);
    }
    runCommand(command?: ICommand): void {
       if(command != null)
          this.command.push(command);
       const commandOnFire = this.command.shift();
       commandOnFire.excute();
    }

}
export class CommandAction
{
    test()
    {
        const receiver = new CommandRecevie();
        const launchCommand = new LaunchCommand(receiver);
        const stopCommand = new StopCommand(receiver);

        const invoker = new Invoker();
        invoker.addCommand(launchCommand);
        invoker.runCommand();
        
        invoker.addCommand(stopCommand);
        invoker.runCommand();
    }
}